package hde;

import robocode.BulletHitEvent;
import robocode.Robot;
import robocode.RobotDeathEvent;
import java.awt.Color;
import robocode.ScannedRobotEvent;
import robocode.HitWallEvent;
import robocode.HitRobotEvent;
import java.util.Random;

/**
 * Robot Ltrboom to conquer all in the ring. 
 * @author Derek Hirano
 *
 */
public class Ltrboom extends Robot {
  boolean targetAlive = false;
  String targetName = "";
  double hypotenuse = 0;
  double angle = 0;
  Random varian = new Random();
  
  /**
   * The real robot run file.
   */
  public void run() {
    setColors(Color.magenta, Color.orange, null);
    setAdjustGunForRobotTurn(true);
    setAdjustRadarForGunTurn(true);
    setAdjustRadarForRobotTurn(true);
    varian.setSeed((long) (getBattleFieldHeight() * getBattleFieldWidth()));

    while (true) {
      turnRadarRight(45);
      while (!targetAlive) {
        turnRadarRight(45);
        ahead(varian.nextDouble() * 108);
        int limit = varian.nextInt(2);
        for (int i = 0; i < limit; i++) {
          switch (((varian.nextInt(19) * varian.nextInt(37)) + 5) % 13) {
            case 1:  turnRight(varian.nextDouble() * varian.nextInt(261)); break;
            case 2:  back(varian.nextDouble() * varian.nextInt(42)); break;
            case 3:  turnLeft(varian.nextDouble() * varian.nextInt(130)); break;
            case 4:  ahead(varian.nextDouble() * varian.nextInt(12)); break;
            case 5:  turnRight(varian.nextDouble() * (varian.nextInt(201) - 125)); break;
            case 6:  back(varian.nextDouble() * varian.nextInt(210)); break;
            case 7:  turnLeft(varian.nextDouble() * (varian.nextInt(192) - 50)); break;
            case 8:  back(varian.nextDouble() * varian.nextInt(191)); break;
            case 9:  ahead(varian.nextDouble() * varian.nextInt(67)); break;
            case 10: back(varian.nextDouble() * varian.nextInt(38)); break;
            case 11: turnRight(varian.nextDouble() * (varian.nextInt(41) - 19)); break;
            case 12: ahead(varian.nextDouble() * varian.nextInt(218)); break;
            case 13: back(varian.nextDouble() * varian.nextInt(310));  break;
            default: ahead(40); break;
          }
        }
      }
      
      while (targetAlive) {
        turnRadarRight(45);
        turnRight(angle);
        ahead(hypotenuse);
      }
    }
  }
  
  /**
   * Fire on scanned robot if the robot is the target; otherwise acquire a target.
   * @param event A robot is scanned.
   */
  public void onScannedRobot (ScannedRobotEvent event) {
    if (!targetAlive) {
      targetName = event.getName();
      targetAlive = true;
    }
    String scannedRobot = event.getName();
    if (targetName.equals(scannedRobot)) {
      hypotenuse = event.getDistance() / 5;
      angle = event.getBearing();
      
      if (event.getDistance() > 80) {
        turnRight(event.getBearing());
        ahead(event.getDistance() / 5);
      }
      
      if (getRadarHeading() < 180) {
        if (getGunHeading() > (getRadarHeading() + 180)) {
          turnGunRight(360 - getGunHeading() + getRadarHeading());
        }
        else {
          turnGunLeft(getGunHeading() - getRadarHeading());
        }
      }
      
      else {
        if (getGunHeading() < (getRadarHeading() - 180)) {
          turnGunLeft(360 - getRadarHeading() + getGunHeading());
        }
        else {
          turnGunRight(getRadarHeading() - getGunHeading());
        }
      }
      
      turnRadarRight(Math.abs(event.getHeading()) - getRadarHeading());
      
      
      if (event.getDistance() <= 200 && event.getName() != null && event.getDistance() > 0.1) {
        fire(Math.min(150 / event.getDistance(), 3));
      }
      scan();
    }
  }

  /**
   * If target robot is destroyed by bullet, acquire new target.
   * @param event Target is destroyed.
   */
  public void onBulletHit (BulletHitEvent event) {
    if (event.getEnergy() < 0.1) {
      targetAlive = false;
      targetName = "";
    }
  }
  
  /**
   * If target robot is destroyed by other means, acquire new target.
   * @param event Target is destroyed.
   */
  public void onRobotDeath (RobotDeathEvent event) {
    String deadRobot = event.getName();
    if (targetName.equals(deadRobot)) {
      targetAlive = false;
      targetName = "";
    }
  }
  
  
 /**
  * Ltrboom turns directly around from wall, if it hit a wall.
  * @param event If robot hits wall.
  */
  public void onHitWall (HitWallEvent event) {
    if (event.getBearing() > 0) {
      turnLeft(180 - event.getBearing());
    }
    
    else if (event.getBearing() < 0) {
      turnRight(180 + event.getBearing());
    }
    
    else {
      turnRight(180);
    }
    
    ahead(60);
  }
  
  /**
   * Ltrboom gets away if it hits another Robot,
   * Otherwise Ltrboom fires at the Robot that ran into Ltrboom.
   * @param event Robot hits another Robot.
   */
  public void onHitRobot (HitRobotEvent event) {
    if (event.isMyFault()) {
      if (event.getBearing() > 0) {
        turnRight(180 - event.getBearing());
      }
      
      else if (event.getBearing() < 0) {
        turnLeft(180 + event.getBearing());
      }
      back(50);
      turnLeft(30);
      back(30);
      turnRight(88);
      back(70);
    }
    
    if (getRadarHeading() < 180) {
      if (getGunHeading() > (getRadarHeading() + 180)) {
        turnGunRight(360 - getGunHeading() + getRadarHeading());
      }
      else {
        turnGunLeft(getGunHeading() - getRadarHeading());
      }
    }
    
    else {
      if (getGunHeading() < (getRadarHeading() - 180)) {
        turnGunLeft(360 - getRadarHeading() + getGunHeading());
      }
      else {
        turnGunRight(getRadarHeading() - getGunHeading());
      }
    }
  }

}
